#include "DoublyNode.hh"

DoublyNode::DoublyNode()
{
	Left = NULL;
	Right = NULL;
	Object = NULL;
}

DoublyNode::~DoublyNode()
{
	ResultOf Result;
	Result = unlink();
	checkErrorWOR(Result, "Fail unlink.");
}

ResultOf DoublyNode::linkLeft(Node* Node)
{
	if (Node == NULL)
	{
		notifyError(Node, "Bad parameter");
		return RETURN_PARAM_ERROR;
	}
	
	ResultOf Result;
	Result = Node->unlink();
	checkErrorWR(Result, "Fail Node->unlink.");
	
	// TODO
	// 연결 도중에 실패로 끝나면, 연결이 뒤죽박죽되버린다.
	// 이 문제를 해결하기 위해서는 각 노드가 백업을 두고 이전 상태로
	// 돌아가는 기능이 필요하다.
	
	if (Left != NULL)
	{
		Result = Node->setLeft(Left);
		checkErrorWR(Result, "Fail Node->setLeft.");
		
		Result = Left->setRight(Node);
		checkErrorWR(Result, "Fail Left->setRight.");
	}
	
	Result = Node->setRight(this);
	checkErrorWR(Result, "Fail Node->setRight.");
	
	Left = Node;
	return RETURN_OK;
}

ResultOf DoublyNode::linkRight(Node* Node)
{
	ResultOf Result;
	Result = Node->unlink();
	checkErrorWR(Result, "Fail Node->unlink.");
	
	// TODO
	// 연결 도중에 실패로 끝나면, 연결이 뒤죽박죽되버린다.
	// 이 문제를 해결하기 위해서는 각 노드가 백업을 두고 이전 상태로
	// 돌아가는 기능이 필요하다.
	
	if (Right != NULL)
	{
		Result = Node->setRight(Right);
		checkErrorWR(Result, "Fail Node->setLeft.");
		
		Result = Right->setLeft(Node);
		checkErrorWR(Result, "Fail Left->setRight.");
	}
	
	Result = Node->setLeft(this);
	checkErrorWR(Result, "Fail Node->setRight.");
	
	Right = Node;
	return RETURN_OK;
}

ResultOf DoublyNode::unlink()
{
	if (Left != NULL)
		Left->setRight(Right);
	
	if (Right != NULL)
		Right->setLeft(Left);
	
	Left = NULL;
	Right = NULL;
	
	return RETURN_OK;
}

ResultOf DoublyNode::attach(void* Obj)
{
	Object = Obj;
	checkNullWR(Object, "Object is NULL.");
	
	return RETURN_OK;
}

ResultOf DoublyNode::setLeft(Node* Node)
{
	Left = Node;
	return RETURN_OK;
}

ResultOf DoublyNode::setRight(Node* Node)
{
	Right = Node;
	return RETURN_OK;
}

void* DoublyNode::tellObject()
{
	return Object;
}

Node* DoublyNode::tellLeft()
{
	return Left;
}

Node* DoublyNode::tellRight()
{
	return Right;
}
